package com.xbq.exceleditor.ui.filechooser

import android.os.Bundle
import android.view.View
import androidx.annotation.IntDef
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.PathUtils
import com.xbq.exceleditor.R
import com.xbq.exceleditor.databinding.FragmentFileByExtentionListBinding
import com.xbq.exceleditor.ui.filechooser.media.FileTypeEnum
import com.xbq.exceleditor.utils.ShellCommandUtils
import com.xbq.exceleditor.utils.value
import com.xbq.xbqsdk.component.activity.VBFragment
import com.xbq.xbqsdk.util.click.onDebouncedClick
import com.xbq.xbqsdk.util.coroutine.await
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import java.util.*

/**
 * Author: liaohaiping
 * Time: 2018-07-25
 * Description:
 */
@AndroidEntryPoint
class FileByExtensionListFragment :
    VBFragment<FragmentFileByExtentionListBinding>() {

    private val adapter by lazy { FileAdapter() }
    private var fileType: FileTypeEnum? = null
    private var searchDirs: MutableList<String> = arrayListOf()

    val wxDirs: List<String> by lazy {
        arrayListOf(
            PathUtils.getExternalStoragePath() + "/Android/data/com.tencent.mm/MicroMsg/Download/",
            PathUtils.getExternalStoragePath() + "/tencent/MicroMsg/"
        )
    }
    val qqDirs: List<String> by lazy {
        arrayListOf(
            PathUtils.getExternalStoragePath() + "/tencent/QQfile_recv/",
            PathUtils.getExternalStoragePath() + "/Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/"
        )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        parseArguments()
        adapter.setOnItemClickListener { adt, view, position ->
            val item = adapter.getItem(position)
            adapter.selectFile(item)
            EventBus.getDefault().post(item)
        }
        binding.fileList.adapter = adapter
        binding.fileList.layoutManager = LinearLayoutManager(requireContext())
        binding.etKeyWord.addTextChangedListener {
            filterFiles()
        }
        binding.ivClearKeyword.onDebouncedClick { clearFilter() }
        binding.ivSearch.onDebouncedClick { filterFiles() }
        filterFiles()
    }

    suspend fun findFiles(dirs: List<String>, keyword: String) = await {
        val list = dirs
            .flatMap {
                ShellCommandUtils.findFilesByExtenstions(
                    it,
                    emptyList(),
                    fileType!!.fileExtensionWithDot
                ).toList()
            }
            .filter { it.isNotEmpty() }
            .map {
                val extFile = ExtFile(it)
                extFile.fileSize = extFile.length()
                extFile.extension = FileUtils.getFileExtension(extFile.name)
                extFile.fileTime = extFile.lastModified()
                extFile
            }
        return@await if (keyword.isNotEmpty()) {
            list.filter { it.name.contains(keyword) }
        } else {
            list
        }
    }


    private fun parseArguments() {
        arguments?.let {
            val fileTypeName = it.getString(EXTRA_FILE_TYPE)
            fileType = FileTypeEnum.valueOf(fileTypeName!!)
            val dirtype = it.getInt(EXTRA_DIR_TYPE)
            searchDirs.clear()
            if (dirtype == DIR_TYPE_QQ) {
                searchDirs.addAll(qqDirs)
            } else {
                searchDirs.addAll(wxDirs)
            }
        }
    }

    private fun clearFilter() {
        binding.etKeyWord.text.clear()
        filterFiles()
    }

    private fun filterFiles() {
        val keyword = binding.etKeyWord.value()
        lifecycleScope.launch {
            val files = findFiles(searchDirs, keyword)
            adapter.setList(files)
            adapter.setEmptyView(R.layout.recycle_no_data)
        }
    }


    @IntDef(DIR_TYPE_QQ, DIR_TYPE_WEIXIN)
    @Retention(AnnotationRetention.SOURCE)
    annotation class SearchDirType

    companion object {
        const val EXTRA_FILE_TYPE = "EXTRA_FILE_TYPE"
        const val EXTRA_DIR_TYPE = "EXTRA_DIR_TYPE"
        const val DIR_TYPE_WEIXIN = 100
        const val DIR_TYPE_QQ = 200

        fun newFragment(
            fileType: FileTypeEnum,
            @SearchDirType dirType: Int = DIR_TYPE_WEIXIN
        ): FileByExtensionListFragment {
            return FileByExtensionListFragment().apply {
                val args = Bundle()
                args.putString(EXTRA_FILE_TYPE, fileType.name)
                args.putInt(EXTRA_DIR_TYPE, dirType)
                arguments = args
            }
        }
    }
}